// file:arch/pymem.c
// autor:jiangxinpeng
// time:2020.12.27
// copyright:(C) 2020-2050 by jiang xinpeng,All right are reserved.

#include <arch/pymem.h>
#include <arch/ards.h>
#include <arch/bootmem.h>
#include <arch/const.h>
#include <arch/address.h>
#include <os/debug.h>
#include <arch/mem_pool.h>
#include <arch/page.h>
#include <lib/stddef.h>
#include <lib/const.h>
#include <lib/type.h>

PRIVATE uint32_t total_pymem_size;
PRIVATE uint32_t reserved_size;
PRIVATE uint32_t kernel_mem, user_mem;
PRIVATE uint32_t mem_node_tnum, mem_node_tbase;
PRIVATE uint32_t mem_node_t_table_size;
PRIVATE mem_node_t *mem_node_t_table;

// get pymem size all page count
uint32_t GetPymemPageCount()
{
        return total_pymem_size / PAGE_SIZE;
}

void PymemInfo()
{
        KPrint("meminfo:\n");
        KPrint("total size: %dMB\n", total_pymem_size / MB);
        KPrint("kernel size: %dMB\n", kernel_mem / MB);
        KPrint("user size: %dMB\n", user_mem / MB);
        KPrint("reserved size: %dMB\n", reserved_size / MB);
}

// init pymem manage
void PymemInit()
{
        uint32_t more_mem;

        reserved_size = KERNEL_MEM_BASE + NULL_MEM_SIZE;
        // get pymemsize from ards block
        total_pymem_size = GetPymemSize();
        // init mem space
        kernel_mem = (total_pymem_size - reserved_size) / 2;
        user_mem = total_pymem_size - reserved_size - kernel_mem;
        if (kernel_mem > (1 * GB + GB / 2))
        {
                user_mem += kernel_mem - (1 * GB + GB / 2);
                kernel_mem = (1 * GB + GB / 2);
        }

        PymemInfo();

        // beacuse boot map only map 20MB,so we now start from kernel mem base to do map
        KernelPageMapEarly(KERNEL_MEM_BASE, KERNEL_MEM_BASE + kernel_mem);

        // init bootmem manage
        // bootmem space in kernel viraddr area
        BootMemInit(BOOT_MEM_BASE + KERNEL_VMM_BASE, BOOT_MEM_SIZE);
        // init mem range
        MemRangeInit(MEM_RANGE_DMA, DMA_MEM_BASE, DMA_MEM_BASE + DMA_MEM_SIZE);
        MemRangeInit(MEM_RANGE_KERNEL,BOOT_MEM_BASE+BOOT_MEM_SIZE, BOOT_MEM_BASE + BOOT_MEM_SIZE+(kernel_mem-BOOT_MEM_SIZE));
        MemRangeInit(MEM_RANGE_USER,KERNEL_MEM_BASE+kernel_mem,KERNEL_MEM_BASE+kernel_mem+user_mem);

        //MemPoolDump();
}
